<template>
  <div class="echarts-network-graph">
    <div ref="containerRef" class="graph-container"></div>
    
    <!-- 工具栏 -->
    <div class="graph-toolbar">
      <a-space direction="vertical">
        <!-- 缩放控制 -->
        <a-button-group>
          <a-tooltip title="放大">
            <a-button @click="zoomIn" size="small">
              <template #icon><zoom-in-outlined /></template>
            </a-button>
          </a-tooltip>
          <a-tooltip title="缩小">
            <a-button @click="zoomOut" size="small">
              <template #icon><zoom-out-outlined /></template>
            </a-button>
          </a-tooltip>
          <a-tooltip title="适应画布">
            <a-button @click="fitView" size="small">
              <template #icon><aim-outlined /></template>
            </a-button>
          </a-tooltip>
        </a-button-group>

        <!-- 布局选择 -->
        <a-select 
          v-model:value="currentLayout" 
          size="small" 
          style="width: 100px"
          @change="changeLayout"
        >
          <a-select-option value="force">力导向</a-select-option>
          <a-select-option value="circular">环形</a-select-option>
          <a-select-option value="none">固定</a-select-option>
        </a-select>

        <!-- 显示选项 -->
        <a-space direction="vertical" size="small">
          <a-switch
            v-model:checked="showLabels"
            size="small"
            checked-children="标签"
            un-checked-children="标签"
            @change="toggleLabels"
          />
          <a-switch
            v-model:checked="showEdgeLabels"
            size="small"
            checked-children="边标签"
            un-checked-children="边标签"
            @change="toggleEdgeLabels"
          />
        </a-space>

        <!-- 筛选控制 -->
        <a-divider style="margin: 8px 0" />
        <div class="filter-section">
          <div class="filter-title">节点类型</div>
          <a-checkbox-group 
            v-model:value="selectedNodeTypes" 
            @change="filterByNodeType"
            size="small"
          >
            <a-checkbox value="CORPORATE">企业</a-checkbox>
            <a-checkbox value="URBAN">城市</a-checkbox>
            <a-checkbox value="CONCEPTUAL">概念</a-checkbox>
            <a-checkbox value="INDIVIDUAL">个人</a-checkbox>
            <a-checkbox value="HYBRID">混合</a-checkbox>
            <a-checkbox value="SYSTEM">系统</a-checkbox>
          </a-checkbox-group>
        </div>

        <div class="filter-section">
          <div class="filter-title">关系强度</div>
          <a-slider
            v-model:value="strengthFilter"
            :min="0"
            :max="1"
            :step="0.1"
            range
            :tooltip-formatter="(value: number) => `${(value * 100).toFixed(0)}%`"
            @change="filterByStrength"
          />
        </div>
      </a-space>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue'
import { message } from 'ant-design-vue'
import { ZoomInOutlined, ZoomOutOutlined, AimOutlined } from '@ant-design/icons-vue'
import * as echarts from 'echarts'
import type { ECharts } from 'echarts'
import type { NetworkVisualizationData, NetworkNode, NetworkEdge } from '@/api/types'

interface Props {
  data: NetworkVisualizationData
  width?: number
  height?: number
}

interface Emits {
  (e: 'nodeClick', node: NetworkNode): void
  (e: 'edgeClick', edge: NetworkEdge): void
  (e: 'nodeDoubleClick', node: NetworkNode): void
  (e: 'canvasClick'): void
}

const props = withDefaults(defineProps<Props>(), {
  width: 800,
  height: 600
})

const emit = defineEmits<Emits>()

// 响应式数据
const containerRef = ref<HTMLElement>()
const currentLayout = ref('force')
const showLabels = ref(true)
const showEdgeLabels = ref(false)
const selectedNodeTypes = ref(['CORPORATE', 'URBAN', 'CONCEPTUAL', 'INDIVIDUAL', 'HYBRID', 'SYSTEM'])
const strengthFilter = ref([0, 1])

// ECharts图实例
let chart: ECharts | null = null

// 节点类型颜色映射
const nodeTypeColors = {
  CORPORATE: '#1890ff',
  URBAN: '#52c41a',
  CONCEPTUAL: '#722ed1',
  INDIVIDUAL: '#fa8c16',
  HYBRID: '#eb2f96',
  SYSTEM: '#13c2c2'
}

// 节点类型图标映射
const nodeTypeIcons = {
  CORPORATE: '🏢',
  URBAN: '🏙️',
  CONCEPTUAL: '💡',
  INDIVIDUAL: '👤',
  HYBRID: '🔗',
  SYSTEM: '⚙️'
}

// 初始化ECharts图
const initChart = () => {
  if (!containerRef.value) return

  chart = echarts.init(containerRef.value)
  
  // 绑定事件
  bindEvents()
  
  // 加载数据
  loadData()
}

// 绑定事件
const bindEvents = () => {
  if (!chart) return

  // 节点点击
  chart.on('click', (params) => {
    if (params.dataType === 'node') {
      const nodeData = params.data as any
      emit('nodeClick', nodeData)
    } else if (params.dataType === 'edge') {
      const edgeData = params.data as any
      emit('edgeClick', edgeData)
    }
  })

  // 节点双击
  chart.on('dblclick', (params) => {
    if (params.dataType === 'node') {
      const nodeData = params.data as any
      emit('nodeDoubleClick', nodeData)
    }
  })

  // 画布点击
  chart.getZr().on('click', (event) => {
    if (!event.target) {
      emit('canvasClick')
    }
  })
}

// 加载数据
const loadData = () => {
  if (!chart || !props.data) return

  const nodes = props.data.nodes.map(node => ({
    id: node.id,
    name: node.name,
    type: node.type,
    status: node.status,
    symbolSize: 30,
    itemStyle: {
      color: nodeTypeColors[node.type as keyof typeof nodeTypeColors] || '#666'
    },
    label: {
      show: showLabels.value,
      position: 'bottom',
      fontSize: 12,
      color: '#333'
    }
  }))

  const edges = props.data.edges.map(edge => ({
    id: edge.id,
    source: edge.source,
    target: edge.target,
    relationshipType: edge.type,
    strength: edge.strength,
    lineStyle: {
      width: Math.max(1, edge.strength * 5),
      color: getEdgeColor(edge.type),
      opacity: 0.7
    },
    label: {
      show: showEdgeLabels.value,
      formatter: edge.type,
      fontSize: 10
    }
  }))

  const option = {
    tooltip: {
      trigger: 'item',
      formatter: (params: any) => {
        if (params.dataType === 'node') {
          return `
            <div>
              <h4>${params.data.name}</h4>
              <p>类型: ${getNodeTypeLabel(params.data.type)}</p>
              <p>状态: ${getStatusLabel(params.data.status)}</p>
            </div>
          `
        } else if (params.dataType === 'edge') {
          return `
            <div>
              <h4>关系信息</h4>
              <p>类型: ${params.data.relationshipType}</p>
              <p>强度: ${(params.data.strength * 100).toFixed(1)}%</p>
            </div>
          `
        }
        return ''
      }
    },
    series: [{
      type: 'graph',
      layout: currentLayout.value,
      data: nodes,
      links: edges,
      roam: true,
      focusNodeAdjacency: true,
      force: {
        repulsion: 1000,
        gravity: 0.1,
        edgeLength: 150,
        layoutAnimation: true
      },
      circular: {
        rotateLabel: true
      },
      emphasis: {
        focus: 'adjacency',
        lineStyle: {
          width: 6
        }
      }
    }]
  }

  chart.setOption(option)
}

// 工具栏功能
const zoomIn = () => {
  if (chart) {
    chart.dispatchAction({
      type: 'dataZoom',
      start: 0,
      end: 80
    })
    message.info('放大')
  }
}

const zoomOut = () => {
  if (chart) {
    chart.dispatchAction({
      type: 'dataZoom',
      start: 0,
      end: 120
    })
    message.info('缩小')
  }
}

const fitView = () => {
  if (chart) {
    chart.resize()
    message.info('适应画布')
  }
}

const changeLayout = (layout: string) => {
  currentLayout.value = layout
  loadData()
  message.success(`已切换到${getLayoutLabel(layout)}布局`)
}

const toggleLabels = (show: boolean) => {
  showLabels.value = show
  loadData()
  message.info(show ? '显示节点标签' : '隐藏节点标签')
}

const toggleEdgeLabels = (show: boolean) => {
  showEdgeLabels.value = show
  loadData()
  message.info(show ? '显示边标签' : '隐藏边标签')
}

const filterByNodeType = (types: string[]) => {
  selectedNodeTypes.value = types
  loadData()
}

const filterByStrength = (range: [number, number]) => {
  strengthFilter.value = range
  loadData()
}

// 辅助函数
const getEdgeColor = (type: string): string => {
  const colors: Record<string, string> = {
    COLLABORATION: '#52c41a',
    COMPETITION: '#f5222d',
    DEPENDENCY: '#1890ff',
    FUSION: '#722ed1',
    COMMUNICATION: '#fa8c16',
    INHERITANCE: '#13c2c2'
  }
  return colors[type] || '#666'
}

const getLayoutLabel = (layout: string): string => {
  const labels: Record<string, string> = {
    force: '力导向',
    circular: '环形',
    none: '固定'
  }
  return labels[layout] || layout
}

const getNodeTypeLabel = (type: string): string => {
  const labels: Record<string, string> = {
    CORPORATE: '企业',
    URBAN: '城市',
    CONCEPTUAL: '概念',
    INDIVIDUAL: '个人',
    HYBRID: '混合',
    SYSTEM: '系统'
  }
  return labels[type] || type
}

const getStatusLabel = (status: string): string => {
  const labels: Record<string, string> = {
    ACTIVE: '活跃',
    INACTIVE: '非活跃',
    EVOLVING: '进化中',
    DORMANT: '休眠'
  }
  return labels[status] || status
}

// 监听数据变化
watch(() => props.data, () => {
  if (chart) {
    loadData()
  }
}, { deep: true })

// 监听尺寸变化
watch([() => props.width, () => props.height], () => {
  if (chart) {
    chart.resize()
  }
})

onMounted(() => {
  nextTick(() => {
    initChart()
  })
})

onUnmounted(() => {
  if (chart) {
    chart.dispose()
  }
})

// 暴露方法给父组件
defineExpose({
  zoomIn,
  zoomOut,
  fitView,
  changeLayout,
  getChart: () => chart
})
</script>

<style scoped>
.echarts-network-graph {
  position: relative;
  width: 100%;
  height: 100%;
}

.graph-container {
  width: 100%;
  height: 100%;
  border: 1px solid #f0f0f0;
  border-radius: 8px;
  background: #fafafa;
}

.graph-toolbar {
  position: absolute;
  top: 16px;
  right: 16px;
  background: rgba(255, 255, 255, 0.95);
  padding: 16px;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  backdrop-filter: blur(4px);
  max-width: 200px;
  z-index: 10;
}

.filter-section {
  margin-top: 8px;
}

.filter-title {
  font-size: 12px;
  color: #666;
  margin-bottom: 4px;
}

:deep(.ant-checkbox-group) {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

:deep(.ant-checkbox-wrapper) {
  font-size: 12px;
}
</style>